/*
 * TicketInfoView.java
 *
 * Created on August 13, 2006, 11:17 PM
 */
package com.floreantpos.ui.views;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTextField;

import net.miginfocom.swing.MigLayout;

import com.floreantpos.main.Application;
import com.floreantpos.model.Ticket;
import com.floreantpos.model.TicketCouponAndDiscount;
import com.floreantpos.model.dao.TicketDAO;
import com.floreantpos.swing.PosButton;
import com.floreantpos.ui.dialog.CouponAndDiscountDialog;
import com.floreantpos.ui.dialog.DiscountListDialog;
import com.floreantpos.ui.dialog.NotesDialog;
import com.floreantpos.ui.dialog.POSMessageDialog;
import com.floreantpos.ui.views.order.OrderController;

/**
 *
 * @author MShahriar
 */
public class TicketDetailView extends JPanel implements ActionListener {

  public final static String VIEW_NAME = "TICKET_DETAIL";

  private com.floreantpos.swing.PosButton btnApplyCoupon;
  private com.floreantpos.swing.PosButton btnViewDiscounts;
  private com.floreantpos.swing.PosButton btnNotes;

  private javax.swing.JLabel lblBalanceDue;
  private javax.swing.JTextField tfCreateTime;
  private javax.swing.JTextField tfGuests;
  private javax.swing.JTextField tfNotes;
  private javax.swing.JTextField tfServerName;
  private javax.swing.JTextField tfSubtotal;
  private javax.swing.JTextField tfTable;
  private javax.swing.JTextField tfTerminal;
  private javax.swing.JTextField tfTicketId;
  private javax.swing.JTextField tfTotal;
  private javax.swing.JTextField tfDue;
  private javax.swing.JTextField tfTotalDiscount;

  private SettleTicketView settleTicketView;

  private SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm");

  private JPanel topPanel;
  private JPanel balanceDuePanel;
  private JPanel buttonPanel;

  private List<Ticket> tickets;

  /**
   * Creates new form TicketInfoView
   */
  public TicketDetailView() {

    setLayout(new BorderLayout(5, 5));

    topPanel = new JPanel(new MigLayout("align 50%"));
    addRow(topPanel, com.floreantpos.POSConstants.TICKET_ID + ":", tfTicketId = new JTextField());
    addRow(topPanel, com.floreantpos.POSConstants.SERVER_NAME + ":", tfServerName = new JTextField());
    addRow(topPanel, com.floreantpos.POSConstants.CREATED + ":", tfCreateTime = new JTextField());
    addRow(topPanel, com.floreantpos.POSConstants.TABLE + ":", tfTable = new JTextField());
    addRow(topPanel, com.floreantpos.POSConstants.GUEST + "(s):", tfGuests = new JTextField());
    addRow(topPanel, com.floreantpos.POSConstants.NOTES, tfNotes = new JTextField());
    addRow(topPanel, com.floreantpos.POSConstants.SUBTOTAL + ":", tfSubtotal = new JTextField());
    addRow(topPanel, com.floreantpos.POSConstants.DISCOUNT + ":", tfTotalDiscount = new JTextField());
    addRow(topPanel, com.floreantpos.POSConstants.TOTAL + ":", tfTotal = new JTextField());

    add(topPanel, BorderLayout.CENTER);

    balanceDuePanel = new JPanel(new MigLayout("align 50%"));
    balanceDuePanel.add(new JSeparator(), "grow, span,w 320");
    JLabel balanceDueTitle = new JLabel(com.floreantpos.POSConstants.BALANCE_DUE + ":");
    balanceDuePanel.add(balanceDueTitle, "newline,grow,span");
    balanceDuePanel.add(lblBalanceDue = new JLabel("0"), "newline,grow,span");

    buttonPanel = new JPanel(new MigLayout("align 50%"));
    buttonPanel.add(new JSeparator(), "newline, grow,span");
    buttonPanel.add(btnApplyCoupon = new PosButton(com.floreantpos.POSConstants.COUPON_DISCOUNT), "w 100, h 50, grow, ax 100%");
    buttonPanel.add(btnViewDiscounts = new PosButton(com.floreantpos.POSConstants.VIEW_DISCOUNTS), "w 100, h 50");
    buttonPanel.add(btnNotes = new PosButton("Observações"), "w 100, h 50");

    JPanel bottomPanel = new JPanel(new BorderLayout(5, 5));
    bottomPanel.add(balanceDuePanel);
    bottomPanel.add(buttonPanel, BorderLayout.SOUTH);

    add(bottomPanel, BorderLayout.SOUTH);

    setOpaque(false);

    balanceDueTitle.setFont(new java.awt.Font("Tahoma", 1, 18));
    balanceDueTitle.setForeground(new java.awt.Color(255, 102, 0));
    balanceDueTitle.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);

    lblBalanceDue.setFont(new java.awt.Font("Tahoma", 1, 36));
    lblBalanceDue.setForeground(new java.awt.Color(255, 102, 0));
    lblBalanceDue.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
    lblBalanceDue.setText("0.0");

    btnApplyCoupon.addActionListener(this);
    btnViewDiscounts.addActionListener(this);
    btnNotes.addActionListener(this);
  }

  private JLabel createLabel(String text) {
    JLabel label = new JLabel(text);
    label.setHorizontalAlignment(JLabel.RIGHT);
    return label;
  }

  private JTextField createTextField(JTextField textField) {
    textField.setEditable(false);
    textField.setBackground(Color.white);
    return textField;
  }

  private void addRow(JPanel panel, String title, JTextField textField) {
    panel.add(createLabel(title), "newline, height pref");
    panel.add(createTextField(textField), "w 250,height pref");
  }

  protected double getTotalAmount() {
    List<Ticket> ticketsToSettle = getTickets();
    if (ticketsToSettle == null) {
      return 0;
    }

    double total = 0;
    for (Ticket ticket : ticketsToSettle) {
      total += ticket.getTotalAmount();
    }
    return total;
  }

  private void doViewDiscounts() {
    try {
      DiscountListDialog dialog = new DiscountListDialog(tickets);
      dialog.open();
      if (!dialog.isCanceled() && dialog.isModified()) {
        updateModel();

        for (Ticket ticket : tickets) {
          TicketDAO.getInstance().saveOrUpdate(ticket);
        }
        updateView();

        if (settleTicketView != null) {
          settleTicketView.updatePaymentView();
        }
      }
    } catch (Exception e) {
      POSMessageDialog.showError(this, com.floreantpos.POSConstants.ERROR_MESSAGE, e);
    }
  }

  private void doApplyCoupon() {
    try {
      for (Ticket ticket : tickets) {
        if (ticket.getCouponAndDiscounts() != null && ticket.getCouponAndDiscounts().size() > 0) {
          POSMessageDialog.showError(com.floreantpos.POSConstants.DISCOUNT_COUPON_LIMIT_);
          return;
        }
      }

      List<Ticket> tickets = getTickets();
      Ticket ticket = tickets.get(0);
      if (ticket.isPaymentTicket()) {
        POSMessageDialog.showError(com.floreantpos.POSConstants.PAYMENT_CANNOT_HAVE_DISCOUNT);
        return;
      } else {
        CouponAndDiscountDialog dialog = new CouponAndDiscountDialog();
        dialog.setTicket(ticket);
        dialog.initData();
        dialog.open();
        if (!dialog.isCanceled()) {
          TicketCouponAndDiscount coupon = dialog.getSelectedCoupon();
          ticket.addTocouponAndDiscounts(coupon);
          updateModel();
          TicketDAO.getInstance().saveOrUpdate(ticket);
          updateView();
          if (settleTicketView != null) {
            settleTicketView.updatePaymentView();
          }
        }
      }
    } catch (Exception e) {
      POSMessageDialog.showError(this, com.floreantpos.POSConstants.ERROR_MESSAGE, e);
    }
  }

  private void updateModel() {
    List<Ticket> ticketsToSettle = getTickets();
    for (Ticket ticket : ticketsToSettle) {
      ticket.calculatePrice();
    }
  }

  public void clearView() {
    tfTicketId.setText("");
    tfServerName.setText("");
    tfCreateTime.setText("");
    tfGuests.setText("");
    tfNotes.setText("");
    tfTable.setText("");
    tfTerminal.setText("");
    tfSubtotal.setText("");
    tfTotalDiscount.setText("");
    tfTotal.setText("");
    tfDue.setText("");

    lblBalanceDue.setText("0");
  }

  private void updateView() {
    List<Ticket> tickets = getTickets();

    if (tickets.size() <= 0) {
      clearView();
      return;
    }

    String currencySymbol = Application.getCurrencySymbol();

    if (tickets.size() == 1) {
      Ticket ticket = tickets.get(0);
      if (ticket.getId() != null) {
        tfTicketId.setText(ticket.getId().toString());
      }
      tfServerName.setText(ticket.getOwner().toString());
      tfCreateTime.setText(dateFormat.format(ticket.getCreateDate()));
      tfGuests.setText(String.valueOf(ticket.getNumberOfGuests()));
      tfTable.setText(ticket.getGuest());
      if (ticket.getNotes() != null) {
        tfNotes.setText(ticket.getNotes());
      }
      tfSubtotal.setText(currencySymbol + " " + Application.formatNumber(ticket.getSubtotalAmount()));
      tfTotalDiscount.setText(currencySymbol + " " + Application.formatNumber(ticket.getDiscountAmount()));
      tfTotal.setText(currencySymbol + " " + Application.formatNumber(ticket.getTotalAmount()));

      lblBalanceDue.setText(Application.formatNumber(ticket.getDueAmount()));
      btnApplyCoupon.setEnabled(true);
      return;
    }

    Ticket firstTicket = tickets.get(0);
    String idString = "";
    String serverName = firstTicket.getOwner().toString();
    String createTime = "";
    int totalGuests = 0;
    String tableNumber = "";
    String ticketNotes = "";
    double subtotal = 0;
    double discount = 0;
    double total = 0;

    for (Iterator iter = tickets.iterator(); iter.hasNext();) {
      Ticket ticket = (Ticket) iter.next();

      if (ticket.getId() != null) {
        idString += "[" + ticket.getId();
        if (iter.hasNext()) {
          idString += "] ";
        } else {
          idString += "]";
        }
      }

      if (ticket.getCreateDate() != null) {
        createTime += "[Pedido " + ticket.getId() + ": " + dateFormat.format(ticket.getCreateDate());
        if (iter.hasNext()) {
          createTime += "] ";
        } else {
          createTime += "]";
        }
      }

      if (ticket.getGuest() != null) {
        tableNumber += "[Pedido " + ticket.getId() + ": " + ticket.getGuest();
        if (iter.hasNext()) {
          tableNumber += "] ";
        } else {
          tableNumber += "]";
        }
      }

      if (ticket.getNotes() != null) {
        ticketNotes += "[Pedido " + ticket.getId() + ": " + ticket.getNotes();
        if (iter.hasNext()) {
          ticketNotes += "] ";
        } else {
          ticketNotes += "]";
        }
      }

      totalGuests += ticket.getNumberOfGuests();
      subtotal += ticket.getSubtotalAmount();
      discount += ticket.getDiscountAmount();
      total += ticket.getTotalAmount();
    }

    tfTicketId.setText(idString);
    tfServerName.setText(serverName);
    tfCreateTime.setText(createTime);
    tfGuests.setText(String.valueOf(totalGuests));
    tfTable.setText(tableNumber);
    tfNotes.setText(ticketNotes);
    tfSubtotal.setText(currencySymbol + Application.formatNumber(subtotal));
    tfTotalDiscount.setText(currencySymbol + Application.formatNumber(discount));
    tfTotal.setText(currencySymbol + Application.formatNumber(total));

    lblBalanceDue.setText(Application.formatNumber(total));

    btnApplyCoupon.setEnabled(false);
  }

  public void setDiscountPanelVisible(boolean b) {
    balanceDuePanel.setVisible(b);
  }

  public boolean isDiscountPanelVisible() {
    return balanceDuePanel.isVisible();
  }

  public void setBalanceDuePanelVisible(boolean b) {
    balanceDuePanel.setVisible(b);
  }

  public boolean isBalanceDuePanelVisible() {
    return balanceDuePanel.isVisible();
  }

  public void setButtonPanelVisible(boolean b) {
    buttonPanel.setVisible(b);
  }

  public SettleTicketView getSettleTicketView() {
    return settleTicketView;
  }

  public void setSettleTicketView(SettleTicketView settleTicketView) {
    this.settleTicketView = settleTicketView;
  }

  public List<Ticket> getTickets() {
    return tickets;
  }

  public void setTickets(List<Ticket> tickets) {
    this.tickets = tickets;

    updateView();
  }

  public void setTicket(Ticket ticket) {
    tickets = new ArrayList<Ticket>(1);
    tickets.add(ticket);

    updateView();
  }

  public void cleanup() {
    tickets = null;
  }

  public void actionPerformed(ActionEvent e) {
    Object source = e.getSource();
    if (source == btnApplyCoupon) {
      doApplyCoupon();
    }
    if (source == btnViewDiscounts) {
      doViewDiscounts();
    }
    if (source == btnNotes) {
      doEditNotes();
    }
  }

  private void doEditNotes() {
    if (tickets.size() == 1) {
      NotesDialog notesDialog = new NotesDialog(Application.getPosWindow(), true);
      notesDialog.setTitle(com.floreantpos.POSConstants.OBSERVATIONS);
      notesDialog.setNote(tickets.get(0).getNotes());
      notesDialog.open();
      if (!notesDialog.isCanceled()) {
        String noteText = notesDialog.getNote();
        noteText = noteText.replaceAll("\\r|\\n", "|");
        tickets.get(0).setNotes(noteText);
        OrderController.saveOrder(tickets.get(0));
      }
    } else {
      POSMessageDialog.showMessage(com.floreantpos.POSConstants.CANNOT_CHANGE_OBS);
    }
  }
}
